/** @file
The module is the platform boot manager dxe.

Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2006 - 2023, Kunlun BIOS, Kunlun Technology (Beijing) Co., Ltd.. All
Rights Reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "PlatformBootManagerDxe.h"

extern UINT16  BootDeviceOrder[8];

CONST EDKII_PLATFORM_BOOT_MANAGER_PROTOCOL mPlatformBootManagerProtocol = {
  EDKII_PLATFORM_BOOT_MANAGER_PROTOCOL_REVISION,
  RefreshAllBootOptions
};

/*
  This function allows platform to refresh all boot options specific to the platform. Within
  this function, platform can make modifications to the auto enumerated platform boot options
  as well as NV boot options.

  @param[in const] BootOptions             An array of auto enumerated platform boot options.
                                           This array will be freed by caller upon successful
                                           exit of this function and output array would be used.

  @param[in const] BootOptionsCount        The number of elements in BootOptions.

  @param[out]      UpdatedBootOptions      An array of boot options that have been customized
                                           for the platform on top of input boot options. This
                                           array would be allocated by REFRESH_ALL_BOOT_OPTIONS
                                           and would be freed by caller after consuming it.

  @param[out]      UpdatedBootOptionsCount The number of elements in UpdatedBootOptions.


  @retval EFI_SUCCESS                      Platform refresh to input BootOptions and
                                           BootCount have been done.

  @retval EFI_OUT_OF_RESOURCES             Memory allocation failed.

  @retval EFI_INVALID_PARAMETER            Input is not correct.

  @retval EFI_UNSUPPORTED                  Platform specific overrides are not supported.
*/

/**
  This function is used to refresh all boot options.

  @param  BootOptions               The Pointer of boot manager load option.
  @param  BootOptionsCount          The Boot Options Count.
  @param  UpdatedBootOptions        The boot manager load option.
  @param  UpdatedBootOptionsCount   The updated boot options count.

  @return EFI_SUCCESS
  @return Others
**/
EFI_STATUS
EFIAPI
RefreshAllBootOptions (
  IN  CONST EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions,
  IN  CONST UINTN                        BootOptionsCount,
  OUT       EFI_BOOT_MANAGER_LOAD_OPTION **UpdatedBootOptions,
  OUT       UINTN                        *UpdatedBootOptionsCount
  )
{
  //CHAR16                                *Path;
  UINT32                                Index;
  UINT16                                DevicePathType;
  UINT8                                 Num;
  UINT8                                 Temp;

  if(BootOptionsCount == 0){
    return EFI_UNSUPPORTED;
  }
  Temp = 0;
  *UpdatedBootOptionsCount = BootOptionsCount;
  *UpdatedBootOptions = AllocateZeroPool(sizeof(EFI_BOOT_MANAGER_LOAD_OPTION)*BootOptionsCount);
  for(Num = 0;Num < sizeof(BootDeviceOrder)/sizeof(UINT16);Num++){
    for(Index = 0;Index < BootOptionsCount;Index++){
      DevicePathType = GetBootDeviceTypeFromDevicePath(BootOptions[Index].FilePath);
      if(DevicePathType == BootDeviceOrder[Num]){
        CopyMem (&(*UpdatedBootOptions)[Temp++], &BootOptions[Index], sizeof(EFI_BOOT_MANAGER_LOAD_OPTION));
      }
    }
  }

  return EFI_SUCCESS;
}

/**
  This function is the entry point of platform boot manager.

  @param  ImageHandle          The EFI handle.
  @param  SystemTable          The Pointer of system table.

  @return EFI_SUCCESS
  @return Others
**/
EFI_STATUS
EFIAPI
PlatformBootManagerEntryPoint (
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )
{
  EFI_STATUS                Status;
  EFI_HANDLE                Handle;

  Handle = NULL;
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Handle,
                  &gEdkiiPlatformBootManagerProtocolGuid, &mPlatformBootManagerProtocol,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  return EFI_SUCCESS;
}
